package com.vietnam.power.admin.controller;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FilenameUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.vietnam.power.constant.AppConfigurationConstant;
import com.vietnam.power.constant.GeneralConstant;
import com.vietnam.power.domain.FileSearchCriteria;
import com.vietnam.power.domain.FileUpload;
import com.vietnam.power.domain.UploadedFile;
import com.vietnam.power.service.FileService;
import com.vietnam.power.service.TransactionService;
import com.vietnam.power.util.FileValidator;

@Controller
@RequestMapping("/admin")
public class FileController {
	private static Logger logger = Logger.getLogger(FileController.class);
	@Autowired
	private MessageSource messageSource;

	@Autowired
	private TransactionService transactionService;

	@Autowired
	private FileService fileService;

	@Autowired
	private FileValidator fileValidator;

	@RequestMapping(value = { "/createFile" }, method = RequestMethod.GET)
	public ModelAndView createFile(HttpServletRequest request, HttpServletResponse response) {
		ModelAndView mav = new ModelAndView("admin/selectFileType");

		mav.addObject("fileTypeList", buildFileTypeList());
		mav.addObject("fileSearch", new FileSearchCriteria());

		mav.addObject("pageTitle", messageSource.getMessage("admin.images.title", null, LocaleContextHolder.getLocale()));
		return mav;
	}

	@RequestMapping(value = { "/createFile" }, method = RequestMethod.POST)
	public ModelAndView createFile(HttpServletRequest request, HttpServletResponse response, @ModelAttribute(value = "fileSearch") FileSearchCriteria s) {
		ModelAndView mav = new ModelAndView("admin/newFile");
		FileUpload fu = new FileUpload();
		fu.setName(s.getName());

		mav.addObject("fileUpload", fu);
		mav.addObject("pageTitle", messageSource.getMessage("admin.images.title", null, LocaleContextHolder.getLocale()));
		return mav;
	}

	@RequestMapping(value = { "/validateFileType" }, method = RequestMethod.POST)
	public @ResponseBody
	String validateArticleGroup(@RequestParam(value = "name") String filename) {
		if (!fileService.validateFileGroup(filename)) {
			return "failed";
		}
		return "success";
	}

	@RequestMapping(value = { "/saveFile" }, method = RequestMethod.POST)
	public ModelAndView saveFile(HttpServletRequest request, HttpServletResponse response, @ModelAttribute(value = "fileUpload") FileUpload fu) {
		ModelAndView mav = new ModelAndView("admin/newFile");
		
		if (fu.getId() == null) {
			fileService.updateFileStatusToActive(fu.getImageId(),fu.getDescription());
		} else {
			fileService.updateFileStatusToActive(fu.getImageId(),fu.getDescription());
			if (fu.getId().intValue() != fu.getImageId().intValue()) {
				String appPath = request.getSession().getServletContext().getRealPath("/");
				fileService.deleteFile(fu.getId(), appPath);
			}
		}
		mav.addObject("mode", GeneralConstant.MODE_VIEW);
		mav.addObject("fileUpload", fileService.getFileById(fu.getImageId()));
		mav.addObject("pageTitle", messageSource.getMessage("admin.images.title", null, LocaleContextHolder.getLocale()));
		return mav;
	}
	
	@RequestMapping(value = { "/updateFile" }, method = RequestMethod.GET)
	public ModelAndView updateFile(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "id", required = true) int id) {
		ModelAndView mav = new ModelAndView("admin/newFile");
		logger.debug("file id: " + id);

		mav.addObject("mode", GeneralConstant.MODE_EDIT);
		mav.addObject("fileUpload", fileService.getFileById(id));
		mav.addObject("pageTitle", messageSource.getMessage("admin.images.title", null, LocaleContextHolder.getLocale()));
		return mav;
	}

	@RequestMapping(value = { "/viewFile" }, method = RequestMethod.GET)
	public ModelAndView viewFile(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "id", required = true) int id) {
		ModelAndView mav = new ModelAndView("admin/newFile");

		mav.addObject("mode", GeneralConstant.MODE_VIEW);
		mav.addObject("fileUpload", fileService.getFileById(id));
		mav.addObject("pageTitle", messageSource.getMessage("admin.images.title", null, LocaleContextHolder.getLocale()));
		return mav;
	}

	@RequestMapping(value = { "/searchFile" }, method = RequestMethod.GET)
	public ModelAndView searchFile(HttpServletRequest request, HttpServletResponse response) {
		ModelAndView mav = new ModelAndView("admin/searchFile");
		Map<String,String> map = buildFileTypeList();
		map.put(null, messageSource.getMessage("admin.article.group.all", null, LocaleContextHolder.getLocale()));
		
		mav.addObject("fileSearh", new FileSearchCriteria());
		mav.addObject("fileTypeList", map);
		mav.addObject("pageTitle", messageSource.getMessage("admin.images.title", null, LocaleContextHolder.getLocale()));
		return mav;
	}

	@RequestMapping(value = { "/searchFile" }, method = RequestMethod.POST)
	public ModelAndView searchFile(HttpServletRequest request, HttpServletResponse response,
			@ModelAttribute(value = "fileSearh") FileSearchCriteria s) {
		ModelAndView mav = new ModelAndView("admin/searchFile");
		Map<String,String> map = buildFileTypeList();
		map.put(null, messageSource.getMessage("admin.article.group.all", null, LocaleContextHolder.getLocale()));
		
		mav.addObject("fileSearh", s);
		mav.addObject("fileTypeList", map);
		mav.addObject("rs", fileService.searchFiles(s));
		mav.addObject("pageTitle", messageSource.getMessage("admin.images.title", null, LocaleContextHolder.getLocale()));
		return mav;
	}

	private Map<String, String> buildFileTypeList() {
		// build order list
		Map<String, String> orderStatusList = new HashMap<String, String>();
		orderStatusList.put(AppConfigurationConstant.FILE_UPLOAD.FILE_ADVERTISING_NAME,
				messageSource.getMessage("admin.file.type.advertising", null, LocaleContextHolder.getLocale()));
		orderStatusList.put(AppConfigurationConstant.FILE_UPLOAD.FILE_BANNER_NAME,
				messageSource.getMessage("admin.file.type.banner", null, LocaleContextHolder.getLocale()));
		orderStatusList.put(AppConfigurationConstant.FILE_UPLOAD.FILE_SLIDER_NAME,
				messageSource.getMessage("admin.file.type.slider", null, LocaleContextHolder.getLocale()));
		orderStatusList.put(AppConfigurationConstant.FILE_UPLOAD.FILE_FOOTER_NAME,
				messageSource.getMessage("admin.file.type.footer", null, LocaleContextHolder.getLocale()));

		return orderStatusList;
	}

	@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
	public @ResponseBody
	String uploadFile(HttpServletRequest request, @ModelAttribute("uploadFile") UploadedFile uploadFile,
			@RequestParam(required = false, value = "fileFor") String fileFor)
			throws IOException {
		int fileId = 0;
		// get absolute path of the application
		String appPath = request.getSession().getServletContext().getRealPath("/");

		for (MultipartFile multipartFile : uploadFile.getMultipartFile()) {
			if (!fileValidator.validateFileSize(multipartFile)) {
				return messageSource.getMessage("admin.file.upload.empty.file", null, LocaleContextHolder.getLocale());
			}
		}

		// save file to hardisk
		for (MultipartFile multipartFile : uploadFile.getMultipartFile()) {
			String fileExt = FilenameUtils.getExtension(multipartFile.getOriginalFilename());
			fileId = fileService.createImages(appPath, multipartFile.getBytes(), fileExt, fileFor);
		}

		return String.valueOf(fileId);
	}

	@RequestMapping(value = "/cropFile", method = RequestMethod.POST)
	public @ResponseBody
	void cropFile(HttpServletRequest request, @RequestParam(required = false, value = "fileId") int fileId,
			@RequestParam(required = false, value = "fileFor") String fileFor, @RequestParam(required = false, value = "x") int x,
			@RequestParam(required = false, value = "y") int y, @RequestParam(required = false, value = "w") int w,
			@RequestParam(required = false, value = "h") int h, @RequestParam(required = false, value = "resizew") int resizew,
			@RequestParam(required = false, value = "resizeh") int resizeh) throws IOException {
		// get absolute path of the application
		String appPath = request.getSession().getServletContext().getRealPath("/");

		fileService.createThumbImage(appPath, fileId, fileFor, x, y, w, h, resizew, resizeh);
	}

	@RequestMapping(value = "/deleteFile", method = RequestMethod.POST)
	public @ResponseBody
	void deleteFile(HttpServletRequest request, @RequestParam(required = false, value = "fileId") int fileId) {
		// get absolute path of the application
		String appPath = request.getSession().getServletContext().getRealPath("/");

		fileService.deleteFile(fileId, appPath);
	}
}
